#include "..\\code\\dataStruct.h"
#include "..\\code\\common.h"

extern void capacitorOverCurrentRelay(Device *device);

extern void capacitorZeroCurrentRelay(Device *device);

extern void capacitorOverVoltageRelay(Device *device);

extern void capacitorLowVoltageRelay(Device *device);

extern void capacitorUBCurrentRelay(Device *device);

extern void capacitorUBVoltageRelay(Device *device);

extern void capacitorTrip(Device *device);

void capacitor(Device *device) {

    // 误码生成替换
    errorDataOperation(device);

    // 如果当前相量数据错误
    if (isDataValid(device, 0) == 0) return;

    // 将采样值存入瞬时值数组
    sample2inst(device);

    // 瞬时值滤波后存入并更新滤波后数组
    dataFilter(device);

    // 利用滤波后数据计算12通道相量, 存入phasor数组
    toPhasor(device);

    if (device->time < STABLE_TIME) {
        // 等待仿真进入稳定状态
        return;
    }

    // 1.过流保护
    capacitorOverCurrentRelay(device);

    // 2.零序过电流保护
    capacitorZeroCurrentRelay(device);

    // 3.过电压保护
    capacitorOverVoltageRelay(device);

    // 4.低电压保护
     capacitorLowVoltageRelay(device);

    // 5.不平衡电流保护
     capacitorUBCurrentRelay(device);

    // 6.不平衡电压保护
     capacitorUBVoltageRelay(device);

    // 保护动作出口
    capacitorTrip(device);

}

/**
 * 电容器过流保护
 * 三相电流最大值大于0.95倍整定值时动作
 * @param device
 */
void capacitorOverCurrentRelay(Device *device) {
    if (device->capacitor.overCurrentEnable == 0) return;
    if (device->capacitor.overCurrentTripFlag == 1) return;

    int phase = 0;

    // I段启动判定
    if (device->capacitor.overCurrentOneStartFlag == 0) {
        double IcA = phasorAbs(device->phasor[3]);
        double IcB = phasorAbs(device->phasor[4]);
        double IcC = phasorAbs(device->phasor[5]);

        double IcMax = max3(IcA, IcB, IcC);

        if (IcMax > 0.95 * device->capacitor.overCurrentOneSetValue) {
            writePlainLog(device, "电容器过电流I段保护启动");
            device->capacitor.overCurrentOneStartFlag = 1;
            device->capacitor.overCurrentOneStartTime = device->time;
        }
    }
    // I段动作判定
    if (device->capacitor.overCurrentOneStartFlag == 1) {
        double IcA = phasorAbs(device->phasor[3]);
        double IcB = phasorAbs(device->phasor[4]);
        double IcC = phasorAbs(device->phasor[5]);

        double IcMax = max3(IcA, IcB, IcC);

        if (device->time > device->capacitor.overCurrentOneStartTime + device->capacitor.overCurrentOneTimeSetValue &&
            IcMax > 0.95 * device->capacitor.overCurrentOneSetValue) {
            device->capacitor.overCurrentTripFlag = 1;
            writePlainLog(device, "电容器过电流I段保护动作");
        }
    }

    // II段启动判定
    if (device->capacitor.overCurrentTwoStartFlag == 0) {
        double IcA = phasorAbs(device->phasor[3]);
        double IcB = phasorAbs(device->phasor[4]);
        double IcC = phasorAbs(device->phasor[5]);

        double IcMax = max3(IcA, IcB, IcC);

        if (IcMax > 0.95 * device->capacitor.overCurrentTwoSetValue) {
            writePlainLog(device, "电容器过电流II段保护启动");
            device->capacitor.overCurrentTwoStartFlag = 1;
            device->capacitor.overCurrentTwoStartTime = device->time;
        }
    }
    // II段动作判定
    if (device->capacitor.overCurrentTwoStartFlag == 1) {
        double IcA = phasorAbs(device->phasor[3]);
        double IcB = phasorAbs(device->phasor[4]);
        double IcC = phasorAbs(device->phasor[5]);

        double IcMax = max3(IcA, IcB, IcC);

        if (device->time > device->capacitor.overCurrentTwoStartTime + device->capacitor.overCurrentTwoTimeSetValue &&
            IcMax > 0.95 * device->capacitor.overCurrentTwoSetValue) {
            device->capacitor.overCurrentTripFlag = 1;
            writePlainLog(device, "电容器过电流II段保护动作");
        }
    }


}


/**
 * 电容器零序过流保护
 * 零序电流大于0.95倍零序电流整定值时动作
 */
void capacitorZeroCurrentRelay(Device *device) {
    if (device->capacitor.zeroCurrentEnable == 0) return;
    // 保护动作后不再判定, 锁存动作结果
    if (device->capacitor.zeroCurrentTripFlag == 1) return;


    int phase = 0;
    // 仅在没有启动的情况下才进行启动判据判别, 避免启动时间被覆盖
    if (device->capacitor.zeroCurrentStartFlag == 0) {
        Phasor IpA = device->phasor[3];
        Phasor IpB = device->phasor[4];
        Phasor IpC = device->phasor[5];

        Phasor zeroPhase = phasorAdd(phasorAdd(IpA, IpB), IpC);
        double zeroAbs = phasorAbs(zeroPhase);

        if (zeroAbs > 0.95 * device->capacitor.zeroCurrentSetValue) {
            writePlainLog(device, "电容器零序过电流保护启动");
            device->capacitor.zeroCurrentStartFlag = 1;
            device->capacitor.zeroCurrentStartTime = device->time;
        }
    }

    // 如果零序保护已经启动才进入判别
    if (device->capacitor.zeroCurrentStartFlag == 1) {
        Phasor IpA = device->phasor[3];
        Phasor IpB = device->phasor[4];
        Phasor IpC = device->phasor[5];

        Phasor zeroPhase = phasorAdd(phasorAdd(IpA, IpB), IpC);
        double zeroAbs = phasorAbs(zeroPhase);
        // 三条件, 时间+条件+(启动)
        if (device->time > device->capacitor.zeroCurrentStartTime + device->capacitor.zeroCurrentTimeSetValue &&
            zeroAbs > 0.95 * device->capacitor.zeroCurrentSetValue) {
            device->capacitor.zeroCurrentTripFlag = 1;
            writePlainLog(device, "电容器零序过电流保护动作");
        }
    }
}

/**
 * 电容器过电压保护
 * 任意大于, 即最大相间电压大于0.98倍过电压整定值, 且开关在合位时动作
 */
void capacitorOverVoltageRelay(Device *device) {
    if (device->capacitor.overVoltageEnable == 0) return;
    // 保护动作后不再判定, 锁存动作结果
    if (device->capacitor.overVoltageTripFlag == 1) return;

    double maxDiff = 0.0;

    Phasor VpA = device->phasor[0];
    Phasor VpB = device->phasor[1];
    Phasor VpC = device->phasor[2];

    Phasor Vab = phasorSub(VpA, VpB);
    Phasor Vbc = phasorSub(VpB, VpC);
    Phasor Vca = phasorSub(VpC, VpA);

    maxDiff = max3(phasorAbs(Vab), phasorAbs(Vbc), phasorAbs(Vca));

    // 仅在没有启动的情况下才进行启动判据判别, 避免启动时间被覆盖
    if (device->capacitor.overVoltageStartFlag == 0) {

        if (maxDiff > 0.98 * device->capacitor.overVoltageSetValue) {
            writePlainLog(device, "电容器过电压保护启动");
            device->capacitor.overVoltageStartFlag = 1;
            device->capacitor.overVoltageStartTime = device->time;
        }
    }

    // 已经启动才进入判别
    if (device->capacitor.overVoltageStartFlag == 1) {
        // 三条件, 时间+条件+(启动)
        if (device->time > device->capacitor.overVoltageStartTime + device->capacitor.overVoltageTimeSetValue &&
            maxDiff > 0.98 * device->capacitor.overVoltageSetValue) {
            device->capacitor.overVoltageTripFlag = 1;
            writePlainLog(device, "电容器过电压保护动作");
        }
    }
}


/**
 * 电容器低电压保护
 * 都小于, 即最大相间电压小于1.02倍低电压整定值, 开关在合位时动作
 */
void capacitorLowVoltageRelay(Device *device) {
    if (device->capacitor.lowVoltageEnable == 0) return;
    // 保护动作后不再判定, 锁存动作结果
    if (device->capacitor.lowVoltageTripFlag == 1) return;


    double maxDiff = 0.0;

    Phasor VpA = device->phasor[0];
    Phasor VpB = device->phasor[1];
    Phasor VpC = device->phasor[2];

    Phasor Vab = phasorSub(VpA, VpB);
    Phasor Vbc = phasorSub(VpB, VpC);
    Phasor Vca = phasorSub(VpC, VpA);

    maxDiff = max3(phasorAbs(Vab), phasorAbs(Vbc), phasorAbs(Vca));

    // 仅在没有启动的情况下才进行启动判据判别, 避免启动时间被覆盖
    if (device->capacitor.lowVoltageStartFlag == 0) {

        if (maxDiff < 1.02 * device->capacitor.lowVoltageSetValue) {
            writePlainLog(device, "电容器低电压保护启动");
            device->capacitor.lowVoltageStartFlag = 1;
            device->capacitor.lowVoltageStartTime = device->time;
        }
    }

    // 已经启动才进入判别
    if (device->capacitor.lowVoltageStartFlag == 1) {
        // 三条件, 时间+条件+(启动)
        if (device->time > device->capacitor.lowVoltageStartTime + device->capacitor.lowVoltageTimeSetValue &&
            maxDiff < 1.02 * device->capacitor.lowVoltageSetValue) {
            device->capacitor.lowVoltageTripFlag = 1;
            writePlainLog(device, "电容器低电压保护动作");
        }
    }
}

/**
 * 不平衡电流保护
 * 不平衡电流大于0.95倍不平衡电流整定值时动作
 */
void capacitorUBCurrentRelay(Device *device) {
    if (device->capacitor.uBCurrentEnable == 0) return;
    // 保护动作后不再判定, 锁存动作结果
    if (device->capacitor.uBCurrentTripFlag == 1) return;

    // 注意不平衡电流的数据位置, 在端口2的第4个位置, 前三个是不平衡电压
    Phasor ubCurrent = device->phasor[9];
    double ubVal = phasorAbs(ubCurrent);

    // 仅在没有启动的情况下才进行启动判据判别, 避免启动时间被覆盖
    if (device->capacitor.uBCurrentStartFlag == 0) {

        if (ubVal > 0.95 * device->capacitor.uBCurrentSetValue) {
            writePlainLog(device, "电容器不平衡电流保护启动");
            device->capacitor.uBCurrentStartFlag = 1;
            device->capacitor.uBCurrentStartTime = device->time;
        }
    }

    // 已经启动才进入判别
    if (device->capacitor.uBCurrentStartFlag == 1) {
        // 三条件, 时间+条件+(启动)
        if (device->time > device->capacitor.uBCurrentStartTime + device->capacitor.uBCurrentTimeSetValue &&
            ubVal > 0.95 * device->capacitor.uBCurrentSetValue) {
            device->capacitor.uBCurrentTripFlag = 1;
            writePlainLog(device, "电容器不平衡电流保护动作");
        }
    }
}

/**
 * 不平衡电压保护
 * 任意一相大于, 也就是最大值大于. 不平衡电压大于0.98倍不平衡电压整定值时动作
 */
void capacitorUBVoltageRelay(Device *device) {
    if (device->capacitor.uBVoltageEnable == 0) return;
    // 保护动作后不再判定, 锁存动作结果
    if (device->capacitor.uBVoltageTripFlag == 1) return;


    double maxVal = 0.0;

    Phasor Vab = device->phasor[6];
    Phasor Vbc = device->phasor[7];
    Phasor Vca = device->phasor[8];

    maxVal = max3(phasorAbs(Vab), phasorAbs(Vbc), phasorAbs(Vca));

    // 仅在没有启动的情况下才进行启动判据判别, 避免启动时间被覆盖
    if (device->capacitor.uBVoltageStartFlag == 0) {

        if (maxVal > 0.98 * device->capacitor.uBVoltageSetValue) {
            writePlainLog(device, "电容器不平衡电压保护启动");
            device->capacitor.uBVoltageStartFlag = 1;
            device->capacitor.uBVoltageStartTime = device->time;
        }
    }

    // 已经启动才进入判别
    if (device->capacitor.uBVoltageStartFlag == 1) {
        // 三条件, 时间+条件+(启动)
        if (device->time > device->capacitor.uBVoltageStartTime + device->capacitor.uBVoltageTimeSetValue &&
            maxVal > 0.98 * device->capacitor.uBVoltageSetValue) {
            device->capacitor.uBVoltageTripFlag = 1;
            writePlainLog(device, "电容器不平衡电压保护动作");
        }
    }
}


/**
 * 动作出口判定
 */
void capacitorTrip(Device *device) {

    if (device->capacitor.overCurrentTripFlag == 1 || device->capacitor.zeroCurrentTripFlag == 1 ||
        device->capacitor.overVoltageTripFlag == 1 || device->capacitor.lowVoltageTripFlag == 1 ||
        device->capacitor.uBVoltageTripFlag == 1 || device->capacitor.uBCurrentTripFlag == 1) {
        int i = 0;
        for (i = 0; i < 3; i++) {
            device->outRes[i] = 1;
        }
        writeLog(device, "电容器保护动作出口");
    }

}


